package com.wesley.schedule.support.schedule;

import com.google.common.collect.Lists;
import com.wesley.schedule.domain.entity.ScheduleJob;
import com.wesley.schedule.domain.entity.ScheduleJobLog;
import com.wesley.schedule.support.enums.JobRunStatus;
import com.wesley.schedule.utils.VarsUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 *
 * </p>
 *
 * @author WangPanYong
 * @since 2020/11/27
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
@Slf4j
public class ScheduleService {


    /**
     * 执行SQL方法名称
     */
    public static final String METHOD_PROXY = "runJob";

    /**
     * 查询运行中的Job
     */
    public List<ScheduleJob> findRunningJobs() {
        // 查询 启用的Job
        return Lists.newArrayList();
    }

    /**
     * 执行Job
     * @param jobId 任务Id
     * @author WangPanYong
     * @since 2020/11/27 16:10
     **/
    public void runJob(String jobId) {

    }

    /**
     * 执行Job
     * @param job 实体
     * @author WangPanYong
     * @since 2020/11/27 16:10
     **/
    public void runJob(ScheduleJob job) {
        Objects.requireNonNull(job, " ====> 调度任务不能为空 ");
        log.info(" ====> 开始执行ScheduleJob ... JobId = {}" , job.getId());

        long currentTime = System.currentTimeMillis();
        String eltSql = VarsUtil.replaceDynParams(job.getJobEtlCode(), currentTime);

        ScheduleJobLog jobLog = new ScheduleJobLog();
        jobLog.setJobId(job.getJobId())
              .setJobEtlSql(eltSql);


        try {
            String ddlSql = job.getJobEtlTarget();
            if (!StringUtils.isEmpty(ddlSql)) {
                // todo 执行 ddl sql
                log.info(" ====> ddl sql 执行成功: \r\n {}" , ddlSql);
            }

            String preSql = VarsUtil.replaceDynParams(job.getJobEtlPreCode(), currentTime);
            if (!StringUtils.isEmpty(job.getJobEtlPreCode())) {
                // todo 执行 pre sql
                log.info(" ====> pre sql 执行成功: \r\n {}" , preSql);
            }

            long beginTime = System.currentTimeMillis();
            // todo 执行 etl sql
            log.info(" ====> elt sql 执行成功: \r\n {}" , eltSql);
            long endTime = System.currentTimeMillis();

            String postSql = VarsUtil.replaceDynParams(job.getJobEtlPostCode(), currentTime);
            if (!StringUtils.isEmpty(postSql)) {
                // todo 执行 post sql
                log.info(" ====> post sql 执行成功: \r\n {}" , postSql);
            }

            jobLog.setJobRunStatus(JobRunStatus.FINISH.code())
                  .setJobStartTime(beginTime)
                  .setJobEndTime(endTime)
                  .setJobTotalRuntime(endTime - beginTime);
        } catch (Exception e) {
            jobLog.setJobRunStatus(JobRunStatus.ERROR.code())
                  .setErrorTimes(1)
                  .setErrorMsg(e.getMessage());
            log.error(" ====> 执行Job失败! JobId: {}", job.getJobId());
            log.error(e.getMessage(), e);
        }

        // todo 执行 写入日志
    }

}
